﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Collections.TreeCollections
{
    public class TreeRegisterTable
    {
        public static TreeRegisterTable TreeClassRegisterTable = new TreeRegisterTable();

        #region Properties
        public TreeRegisterClass this[Type index] { get { return (TreeRegisterClass)_registerTable[index]; } }
        public TreeRegisterClass this[string index] { get { return getRegisterClass(index); } }

        public Type[] Keys { get { return getKeys(); } }
        public TreeRegisterClass[] Values { get { return getValues(); } }
        #endregion

        #region Fields

        /// <summary>
        /// The list contains the object type information which this tree support.
        /// Key: Type
        /// </summary>        /// Value: TreeRegisterClass
        private Hashtable _registerTable;
        #endregion

        private TreeRegisterTable()
        {
            _registerTable = new Hashtable();
        }

        /// <summary>
        /// Register Tree Class
        /// </summary>
        /// <param name="register"></param>
        public void RegisterTreeClass(TreeRegisterClass register)
        {
            _registerTable.Add(register.TreeType, register);
        }
        /// <summary>
        /// Contain Type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public bool ContainsType(Type type)
        {
            return _registerTable.ContainsKey(type);
        }
        /// <summary>
        /// Contains Type
        /// </summary>
        /// <param name="typeFullName"></param>
        /// <returns></returns>
        public bool ContainsType(string typeFullName)
        {
            Type type = Convert(typeFullName);
            if (type == null)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// Convert type full name string to type
        /// </summary>
        /// <param name="fullName"></param>
        /// <returns></returns>
        public Type Convert(string typeFullName)
        {
            Type type = null;
            foreach (Type tmpType in this.Keys)
            {
                if (tmpType.FullName == typeFullName)
                {
                    type = tmpType;
                    break;
                }
            }
            return type;
        }

        /// <summary>
        /// Get Keys
        /// </summary>
        /// <returns></returns>
        private Type[] getKeys()
        {
            Type[] keys = new Type[_registerTable.Count];
            int index = 0;
            foreach (Type type in _registerTable.Keys)
            {
                keys[index++] = type;
            }
            return keys;
        }
        /// <summary>
        /// Get Values
        /// </summary>
        /// <returns></returns>
        private TreeRegisterClass[] getValues()
        {
            TreeRegisterClass[] values = new TreeRegisterClass[_registerTable.Count];
            int index = 0;
            foreach (TreeRegisterClass obj in _registerTable.Values)
            {
                values[index++] = obj;
            }
            return values;
        }

        /// <summary>
        /// Get Register Class
        /// </summary>
        /// <param name="typeFullName"></param>
        /// <returns></returns>
        private TreeRegisterClass getRegisterClass(string typeFullName)
        {
            if (!ContainsType(typeFullName))
            {
                throw new TreeRegisterException(
                    string.Format("Type:{0} did not registered.", typeFullName));
            }
            Type type = Convert(typeFullName);
            return this[type];
        }
    }
}
